#!/usr/bin/python3
# -*- coding: UTF-8 -*-

# Python3 标准库
# https://docs.python.org/zh-cn/3/library/index.html
# 文件和目录访问
# https://docs.python.org/zh-cn/3/library/filesys.html

# version: 3.11.4
# 执行 python gallery.py
# 创建空白__init__.py

# 学习到的语法
# 1、导入模块
# from pathlib import Path
# from pathlib import *
# import requests
# 2、安装模块
# pip3 install requests
# 3、自定义方法def
# def printName(depth, name, ti, len):
# 4、自定义模块：文件名和class保持一致，根据目录结果进行导入模块
# class Files():
#     @staticmethod
#     def hash_file(method, filepath):
# 5、正则表达式
# match = re.search(md5r % Files.md5_file(fName), fName)
# if match:
#   print(match.groups(), match.group(1))
#
# re.sub(r"(.*)", r"\g<1>", fName)
# 查找替换\g<1>类似于match.group(1)
#
# 6、字符串占位符
# "log: version %s" % "v3.11.4"
# 7、print不换行，通过给end赋值，替换默认的\n
# print("|   ", end="")
#
# 8、文件操作
# path = "C:\\project\\gallery"
# # <class 'str'>
# print(type(path))
# p = Path(path)
# # <class 'pathlib.WindowsPath'>
# print(type(p))
# sub= [i for i in p.iterdir()]
# # <class 'list'>
# print(type(sub))
# print(len(sub))
# l = list(sub)
# print(len(l))
# # <class 'list'>
# print(type(l))
# print(p.exists())
# print(p)
# print(p.name)
# print(p.absolute())
# name = os.fspath(p)
# print(name)
# # <class 'str'>
# print(type(name))
# print(type(Path(name)))
# f.rename("newName")


# 引入模块
# import requests
import os
import sys
import time
import datetime
import random
import math
import re
import json
import urllib
# 针对日常的文件和目录管理任务，:mod:shutil 模块提供了一个易于使用的高级接口:
import shutil
# glob模块提供了一个函数用于从目录通配符搜索中生成文件列表:
import glob
# 以下模块直接支持通用的数据打包和压缩格式：zlib，gzip，bz2，zipfile，以及 tarfile。
import zlib
# doctest模块提供了一个工具，扫描模块并根据程序中内嵌的文档字符串执行测试。
import doctest
import hashlib
from pathlib import Path


# 自定义module，用来获取file的md5校验值
class Files():

    @staticmethod
    def hash_file(method, filepath):
        """Calculate a hash on a file by path.
        @param method: callable hashing method
        @param path: file path
        @return: computed hash string
        """
        f = open(filepath, "rb")
        h = method()
        while True:
            buf = f.read(1024 * 1024)
            if not buf:
                break
            h.update(buf)
        return h.hexdigest()

    @staticmethod
    def md5_file(filepath):
        return Files.hash_file(hashlib.md5, filepath)

    @staticmethod
    def sha1_file(filepath):
        return Files.hash_file(hashlib.sha1, filepath)

    @staticmethod
    def sha256_file(filepath):
        return Files.hash_file(hashlib.sha256, filepath)

    pass


# 需要跳过的文件：不检查md5重复、不检查文件名格式、不输出到文件树
skipSet = {".git", ".idea", ".gitignore", "__init__.py", \
           "000000-file-format：category-filName-md5-yyyyMMddHHmmss.ext.md", \
           "00000-gallery.py", "LICENSE", "README.md", "test.py"}

# markdown格式
markdownFormat = "![](https://gitee.com/tec-cloud/gallery/raw/main/%s)"


# 检查md5重复、检查文件名格式
def checkDuplicationAndRename(filepath):
    # 图片当前目录
    p = Path(filepath)
    # 遍历当前目录，拿到所有文件（不包含子目录）
    it = iter([i for i in p.iterdir() if i.is_file()])

    # 检查md5重复
    md5Set = set(["blank-place-holder"])

    for f in it:
        fName = f.name
        fullPath = os.fspath(f)
        md5 = Files.md5_file(fullPath)
        if not fName in skipSet:
            if md5 in md5Set:
                print("重复的文件名：[", fullPath, "]\nmd5：[", md5, "]\n")
            else:
                md5Set.add(md5)

        # 去掉空格
        if f.name.find(" ") > 0:
            print("包含空格的文件名：[", fullPath, "]\nmd5：[", md5, "]\n")
            # print(f.rename(f.name.replace(" ", "-")))

        # file format：category-filName-md5-yyyyMMddHHmmss.ext
        r = "([\u4e00-\u9fa5、\\w\\-\\s\\.（）]+)(\\w{32}-\\d{14}\\.\\w{3,4})$"
        md5r = "([\u4e00-\u9fa5、\\w\\-\\s\\.（）]+)?(%s-\\d{14}\\.\\w{3,4})"
        # 非file format
        # fmt = r
        fmt = md5r % Files.md5_file(fName)
        if (f.name not in skipSet) and (not re.search(fmt, fName)):
            print("需要重命名的文件名：[", fullPath, "]\nmd5：[", md5, "]\n")
            # m = re.search(fmt, fName)
            # if m:
            # newName = re.sub(fmt, r"\g<2>-\g<1>\g<3>", fName)
            # f.rename(newName)
    pass


def doListTree(filepath, depth):
    p = Path(filepath)

    if not p.exists:
        return False

    # 处理子文件夹
    dlist = [d for d in p.iterdir() if d.is_dir() and not d.name in skipSet]
    di = 0
    for d in dlist:
        di += 1
        printName(depth, d.name, di, len(dlist))
        doListTree(d, depth + 1)

    # 处理文件
    flist = [f for f in p.iterdir() if f.is_file() and not f.name in skipSet]
    fi = 0
    for f in flist:
        fi += 1
        # listFolder(f, depth + 1)
        printName(depth, f.name, fi, len(flist))
    pass


# 输出文件名
def printName(depth, name, ti, len):
    while depth > 1:
        depth = depth - 1
        print("|   ", "")
    # 当前目录只有一个文件，输出├──
    if len == 1:
        print("├──", name)
    # 当前目录的第一个文件，输出╭──
    elif ti == 1:
        print("╭──", name)
    # 当前目录的最后一个文件，输出╰──
    elif ti == len:
        print("╰──", name)
    else:
        print("├──", name)
    pass


def listTree(filepath):
    doListTree(filepath, 1)
    pass


directoriesCount = 0
filesCount = 0


# markdown格式的文件清单
def doListMarkDown(filepath):
    global directoriesCount
    global filesCount
    p = Path(filepath)

    if not p.exists:
        return False

    # 处理子文件夹
    dlist = [d for d in p.iterdir() if d.is_dir() and not d.name in skipSet]
    for d in dlist:
        directoriesCount += 1
        doListMarkDown(d)

    # 处理文件
    flist = [f for f in p.iterdir() if f.is_file() and not f.name in skipSet]
    for f in flist:
        filesCount += 1
        print(markdownFormat % f.name)
    pass


def listMarkDown(filepath):
    doListMarkDown(filepath)
    print("%d directories, %d files" % (directoriesCount, filesCount))
    pass


path = "C:\\project\\gallery"
checkDuplicationAndRename(path)
listTree(path)
listMarkDown(path)
print("GG")
pass
